/*
  KeePass Password Safe - The Open-Source Password Manager
  Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using KeePass.Util.Spr;

using KeePassLib;
using KeePassLib.Collections;
using KeePassLib.Delegates;
using KeePassLib.Utility;

namespace KeePass.Util
{
  /// <summary>
  /// This class contains various static functions for entry operations.
  /// </summary>
  public static class EntryUtil
  {

    // Old format name (<= 2.14): "KeePassEntriesCF"
    public const string ClipFormatEntries = "KeePassEntriesCX";

    public static string FillPlaceholders(string strText, SprContext ctx)
    {
      if ((ctx == null) || (ctx.Entry == null)) return strText;

      string str = strText;

      /*NOT SUPPORTED CURRENTLY	if((ctx.Flags & SprCompileFlags.NewPassword) != SprCompileFlags.None)
              str = ReplaceNewPasswordPlaceholder(str, ctx);

          if((ctx.Flags & SprCompileFlags.HmacOtp) != SprCompileFlags.None)
              str = ReplaceHmacOtpPlaceholder(str, ctx);
*/
      return str;
    }

    /*		private static string ReplaceNewPasswordPlaceholder(string strText,
                SprContext ctx)
            {
                PwEntry pe = ctx.Entry;
                PwDatabase pd = ctx.Database;
                if((pe == null) || (pd == null)) return strText;

                string str = strText;

                const string strNewPwPlh = @"{NEWPASSWORD}";
                if(str.IndexOf(strNewPwPlh, StrUtil.CaseIgnoreCmp) >= 0)
                {
                    ProtectedString psAutoGen;
                    PwgError e = PwGenerator.Generate(out psAutoGen,
                        Program.Config.PasswordGenerator.AutoGeneratedPasswordsProfile,
                        null, Program.PwGeneratorPool);
                    psAutoGen = psAutoGen.WithProtection(pd.MemoryProtection.ProtectPassword);

                    if(e == PwgError.Success)
                    {
                        pe.CreateBackup(pd);
                        pe.Strings.Set(PwDefs.PasswordField, psAutoGen);
                        pe.Touch(true, false);
                        pd.Modified = true;

                        string strIns = SprEngine.TransformContent(psAutoGen.ReadString(), ctx);
                        str = StrUtil.ReplaceCaseInsensitive(str, strNewPwPlh, strIns);
                    }
                }

                return str;
            }
    */

    public static bool EntriesHaveSameParent(PwObjectList<PwEntry> v)
    {
      if (v == null) { Debug.Assert(false); return true; }
      if (v.UCount == 0) return true;

      PwGroup pg = v.GetAt(0).ParentGroup;
      foreach (PwEntry pe in v)
      {
        if (pe.ParentGroup != pg) return false;
      }

      return true;
    }

    public static void ReorderEntriesAsInDatabase(PwObjectList<PwEntry> v,
        PwDatabase pd)
    {
      if ((v == null) || (pd == null)) { Debug.Assert(false); return; }
      if (pd.RootGroup == null) { Debug.Assert(false); return; } // DB must be open

      PwObjectList<PwEntry> vRem = v.CloneShallow();
      v.Clear();

      EntryHandler eh = delegate (PwEntry pe)
      {
        int p = vRem.IndexOf(pe);
        if (p >= 0)
        {
          v.Add(pe);
          vRem.RemoveAt((uint)p);
        }

        return true;
      };

      pd.RootGroup.TraverseTree(TraversalMethod.PreOrder, null, eh);

      foreach (PwEntry peRem in vRem) v.Add(peRem); // Entries not found
    }


    public static string CreateSummaryList(PwGroup pgItems, bool bStartWithNewPar)
    {
      List<PwEntry> l = pgItems.GetEntries(true).CloneShallowToList();
      string str = CreateSummaryList(pgItems, l.ToArray());

      if ((str.Length == 0) || !bStartWithNewPar) return str;
      return (MessageService.NewParagraph + str);
    }

    public static string CreateSummaryList(PwGroup pgSubGroups, PwEntry[] vEntries)
    {
      int nMaxEntries = 10;
      string strSummary = string.Empty;

      if (pgSubGroups != null)
      {
        PwObjectList<PwGroup> vGroups = pgSubGroups.GetGroups(true);
        if (vGroups.UCount > 0)
        {
          StringBuilder sbGroups = new StringBuilder();
          sbGroups.Append("- ");
          uint uToList = Math.Min(3U, vGroups.UCount);
          for (uint u = 0; u < uToList; ++u)
          {
            if (sbGroups.Length > 2) sbGroups.Append(", ");
            sbGroups.Append(vGroups.GetAt(u).Name);
          }
          if (uToList < vGroups.UCount) sbGroups.Append(", ...");
          strSummary += sbGroups.ToString(); // New line below

          nMaxEntries -= 2;
        }
      }

      int nSummaryShow = Math.Min(nMaxEntries, vEntries.Length);
      if (nSummaryShow == (vEntries.Length - 1)) --nSummaryShow; // Plural msg

      for (int iSumEnum = 0; iSumEnum < nSummaryShow; ++iSumEnum)
      {
        if (strSummary.Length > 0) strSummary += MessageService.NewLine;

        PwEntry pe = vEntries[iSumEnum];
        strSummary += ("- " + StrUtil.CompactString3Dots(
            pe.Strings.ReadSafe(PwDefs.TitleField), 39));
        if (PwDefs.IsTanEntry(pe))
        {
          string strTanIdx = pe.Strings.ReadSafe(PwDefs.UserNameField);
          if (!string.IsNullOrEmpty(strTanIdx))
            strSummary += (@" (#" + strTanIdx + @")");
        }
      }

      return strSummary;
    }
  }
}
